package android.slc.appbase.ui.widget.grid;

import javafx.scene.Node;
import javafx.scene.layout.ColumnConstraints;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.Priority;
import javafx.scene.layout.RowConstraints;

import java.util.List;

/**
 * 自动平分网格布局
 */
public class SlcLinearLayout extends GridPane {

    private static final String LAYOUT_WEIGHT = "slc-layout-weight";

    public static void setLayoutWeight(Node child, Double value) {
        setConstraint(child, LAYOUT_WEIGHT, value);
    }

    public static Double getLayoutWeight(Node child) {
        return (Double) getConstraint(child, LAYOUT_WEIGHT);
    }

    private static void setConstraint(Node node, Object key, Object value) {
        if (value == null) {
            node.getProperties().remove(key);
        } else {
            node.getProperties().put(key, value);
        }
        if (node.getParent() != null) {
            node.getParent().requestLayout();
        }
    }

    private static Object getConstraint(Node node, Object key) {
        if (node.hasProperties()) {
            Object value = node.getProperties().get(key);
            if (value != null) {
                return value;
            }
        }
        return null;
    }

    private Orientation orientation = Orientation.HORIZONTAL;
    private CrossAxisSize crossAxisSize = CrossAxisSize.WRAP_CONTENT;

    public void setOrientation(Orientation orientation) {
        this.orientation = orientation;
    }

    public Orientation getOrientation() {
        return orientation;
    }

    public void setCrossAxisSize(CrossAxisSize crossAxisSize) {
        this.crossAxisSize = crossAxisSize;
    }

    public CrossAxisSize getCrossAxisSize() {
        return crossAxisSize;
    }

    @Override
    protected void layoutChildren() {
        formatColumn(getChildren());
        super.layoutChildren();
    }

    /**
     * 格式化列
     *
     * @param children
     */
    private void formatColumn(List<Node> children) {
        int nodeCount = children.size();
        //计算权重
        double sunWeight = 0;
        for (Node child : children) {
            Double weight = (Double) child.getProperties().get(LAYOUT_WEIGHT);
            if (weight != null) {
                sunWeight += weight;
            }
        }
        //如果是竖的
        if (getOrientation() == Orientation.VERTICAL) {
            int rowConstraintCount = getRowConstraints().size();
            if (nodeCount > rowConstraintCount) {
                for (int i = 0; i < nodeCount - rowConstraintCount; i++) {
                    RowConstraints constraints = new RowConstraints();
                    getRowConstraints().add(constraints);
                }
            } else if (nodeCount < rowConstraintCount) {
                getRowConstraints().subList(nodeCount, rowConstraintCount).clear();
            }
            if (getColumnConstraints().size() == 0) {
                ColumnConstraints columnConstraints = new ColumnConstraints();
                if (getCrossAxisSize() == CrossAxisSize.MATCH_PARENT) {
                    columnConstraints.setHgrow(Priority.ALWAYS);
                } else {
                    columnConstraints.setHgrow(Priority.NEVER);
                }
                getColumnConstraints().setAll(columnConstraints);
            }
            List<RowConstraints> rowConstraintsList = getRowConstraints();
            for (int nodeIndex = 0; nodeIndex < nodeCount; nodeIndex++) {
                Node node = children.get(nodeIndex);
                Double weight = (Double) node.getProperties().get(LAYOUT_WEIGHT);
                RowConstraints rowConstraints = rowConstraintsList.get(nodeIndex);
                if (weight != null) {
                    rowConstraints.setPercentHeight(100 * weight / sunWeight);
                }
                GridPane.setConstraints(node, 0, nodeIndex);
            }
        } else {
            //如果是横的
            int columnConstraintCount = getColumnConstraints().size();
            if (nodeCount > columnConstraintCount) {
                for (int i = 0; i < nodeCount - columnConstraintCount; i++) {
                    ColumnConstraints constraints = new ColumnConstraints();
                    getColumnConstraints().add(constraints);
                }
            } else if (nodeCount < columnConstraintCount) {
                getColumnConstraints().subList(nodeCount, columnConstraintCount).clear();
            }
            if (getRowConstraints().size() == 0) {
                RowConstraints rowConstraints = new RowConstraints();
                if (getCrossAxisSize() == CrossAxisSize.MATCH_PARENT) {
                    rowConstraints.setVgrow(Priority.ALWAYS);
                } else {
                    rowConstraints.setVgrow(Priority.NEVER);
                }
                getRowConstraints().setAll(rowConstraints);
            }
            List<ColumnConstraints> columnConstraintsList = getColumnConstraints();
            for (int nodeIndex = 0; nodeIndex < nodeCount; nodeIndex++) {
                Node node = children.get(nodeIndex);
                Double weight = (Double) node.getProperties().get(LAYOUT_WEIGHT);
                ColumnConstraints columnConstraints = columnConstraintsList.get(nodeIndex);
                if (weight != null) {
                    columnConstraints.setPercentWidth(100 * weight / sunWeight);
                }
                GridPane.setConstraints(node, nodeIndex, 0);
            }
        }

    }

    public enum Orientation {
        HORIZONTAL,
        VERTICAL
    }

    public enum CrossAxisSize {
        MATCH_PARENT,
        WRAP_CONTENT
    }
}
